﻿namespace WebPacker.Tests.Configuration
{
	using System.Collections.Generic;
	using System.IO;
	using System.Linq;
	using System.Xml;
	using NUnit.Framework;
	using WebPacker.Configuration;
	using WebPacker.Packs;

	[TestFixture]
	public class PackFileInfoTest
	{
		[Test]
		public void SerializeTest()
		{
			var items = GetTestItems();
			var expected = GetTestXml();
			var writer = new StringWriter();
			PackFileInfo.Serialize(new XmlTextWriter(writer), items.ToArray());
			Assert.AreEqual(expected, writer.ToString());
		}

		[Test]
		public void DeserializeTest()
		{
			var xml = GetTestXml();
			var expected = GetTestItems();
			var actual = PackFileInfo.Deserialize(new XmlTextReader(new StringReader(xml))).ToArray();
			Assert.IsNotNull(actual);
			Assert.AreEqual(expected.Length, actual.Length);
			Assert.That(actual, Is.EquivalentTo(expected).Using(new PackFileInfoEqualityComparer()));
		}

		[Test]
		public void SerializeFileTest()
		{
			var filePath = TestHelper.GetFullPath(@"samples\packs.temp.build.xml");
			var expected = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packs>\n  <pack name=\"test\" type=\"javaScript\">test.js</pack>\n  <pack name=\"test\" type=\"css\">23140723748.css</pack>\n</packs>";

			var items = new PackFileInfo[]
			{
				new PackFileInfo(PackType.JavaScript, "test", "test.js"),
				new PackFileInfo(PackType.Css, "test", "23140723748.css"),
			};

			PackFileInfo.Serialize(filePath, items.ToArray());
			
			var actual = File.ReadAllText(filePath);
			Assert.IsNotNull(actual);
			Assert.AreEqual(expected, actual.Replace("\r", string.Empty));
		}

		[Test]
		public void DeserializeFileTest()
		{
			var filePath = TestHelper.GetFullPath(@"samples\configuration\packs.build.xml");

			var expected = new PackFileInfo[]
			{
				new PackFileInfo(PackType.JavaScript, "test", "test.js"),
				new PackFileInfo(PackType.Css, "test", "23140723748.css"),
			};

			var actual = PackFileInfo.Deserialize(filePath).ToArray();
			Assert.IsNotNull(actual);
			Assert.AreEqual(expected.Length, actual.Length);
			Assert.That(actual, Is.EquivalentTo(expected).Using(new PackFileInfoEqualityComparer()));
		}

		private string GetTestXml()
		{
			return "<packs><pack name=\"scripts\" type=\"javaScript\">scripts.12345.js</pack><pack name=\"styles\" type=\"css\">jhjk34hrh34khr34yh.css</pack><pack name=\"test\" type=\"javaScript\">mnwekdopicsdm.js</pack></packs>";
		}

		private PackFileInfo[] GetTestItems()
		{
			return new PackFileInfo[] 
			{
				new PackFileInfo(PackType.JavaScript, "scripts", "scripts.12345.js"),
				new PackFileInfo(PackType.Css, "styles", "jhjk34hrh34khr34yh.css"),
				new PackFileInfo(PackType.JavaScript, "test", "mnwekdopicsdm.js")
			};
		}

		private class PackFileInfoEqualityComparer : IEqualityComparer<PackFileInfo>
		{
			public bool Equals(PackFileInfo x, PackFileInfo y)
			{
				if (x == null || y == null)
				{
					return false;
				}

				if (x.PackName == y.PackName && x.PackType == y.PackType)
				{
					Assert.AreEqual(x.FileName, y.FileName);
					return true;
				}

				return false;
			}

			public int GetHashCode(PackFileInfo obj)
			{
				return obj.GetHashCode();
			}
		}
	}
}
